package com.sneakxy.mybatis.commons.repository.query.executor;

import java.lang.reflect.Method;

import org.apache.ibatis.binding.MapperMethod.ParamMap;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.xmltags.DynamicSqlSource;
import org.apache.ibatis.scripting.xmltags.TextSqlNode;

import com.sneakxy.mybatis.commons.orm.MybatisEntityManager;
import com.sneakxy.mybatis.commons.repository.query.parser.MybatisPartTree;

/**
 * @author 潜行的青衣
 */
public class CountRepositoryExecutor extends AbstractRepositoryExecutor<Long> {

	/**
	 * @param entityManager
	 * @param loader
	 * @param method
	 * @param type
	 */
	public CountRepositoryExecutor(MybatisEntityManager entityManager, Class<?> loader, String method,
			Class<?>... type) {
		super(entityManager, loader, method, type);
	}

	/**
	 * @param entityManager
	 * @param method
	 */
	public CountRepositoryExecutor(MybatisEntityManager entityManager, Method method) {
		super(entityManager, method);
	}

	/* (non-Javadoc)
	 * @see com.sneakxy.mybatis.commons.repository.query.executor.RepositoryExecutor#execute(java.lang.Object[])
	 */
	@Override
	public Long execute(Object... parameters) {
		Object parameterObject = this.createParameterObject(parameters, false);
		return this.getEntityManager().getSqlSessionTemplate().selectOne(getStatement(), parameterObject);
	}

	/* (non-Javadoc)
	 * @see com.sneakxy.mybatis.commons.repository.query.executor.AbstractRepositoryExecutor#onBuildStatment()
	 */
	@Override
	protected void onBuildStatment() {
		StringBuilder sqlBuilder = new StringBuilder();
		sqlBuilder.append("SELECT COUNT(*) ").append(" FROM ${").append(MybatisPartTree.GENERIC_NAME_PREFIX).append("1} ");
		String id = this.getStatement();
		String sql = sqlBuilder.toString();
		SqlCommandType sqlCommandType  = SqlCommandType.SELECT;
		SqlSource sqlSource = new DynamicSqlSource(this.getEntityManager().getConfiguration(), new TextSqlNode(sql));
		this.getEntityManager().addMappedStatement(id, sqlSource, sqlCommandType, ParamMap.class, Long.class);
	}

}
